package com.douban.app.service.impl;

import com.douban.app.model.Subject;
import com.douban.app.service.SubjectService;
import com.mongodb.client.result.DeleteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class SubjectServiceImpl implements SubjectService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private SubjectService subjectService;

    @Override
    public Subject addSubject(Subject subject) {
        if (subject == null) {
            return null;
        }
        mongoTemplate.insert(subject);
        return subject;
    }

    @Override
    public Subject get(String subjectId) {
        if (subjectId == null || subjectId == "") {
            return null;
        }
        return mongoTemplate.findById(subjectId, Subject.class);
    }

    @Override
    public List<Subject> getSubjects(String type) {
        if (type == null || type == "") {
            return null;
        }

        Query query = new Query(Criteria.where("subjectType").is(type));

        List<Subject> subjects = mongoTemplate.find(query, Subject.class);

        return subjects;
    }

    @Override
    public List<Subject> getSubjects(String type, String subType) {
        if (type.isEmpty() && subType.isEmpty()) {
            return null;
        }
        Criteria criteria = new Criteria();
        List<Criteria> subCris = new ArrayList();
        subCris.add(Criteria.where("subjectType").is(type));
        subCris.add(Criteria.where("subjectSubType").is(subType));
        criteria.andOperator(subCris.toArray(new Criteria[]{}));
        Query query = new Query(criteria);

        List<Subject> subjects = mongoTemplate.find(query, Subject.class);

        return subjects;
    }

    @Override
    public boolean delete(String subjectId) {
        if (subjectId.isEmpty()) {
            return false;
        }
        DeleteResult remove = mongoTemplate.remove(subjectService.get(subjectId));
        return remove.getDeletedCount() > 0;
    }

    @Override
    public boolean modify(Subject subject) {
        if (subject.getSongIds() != null) {
            subject.setGmtModified(LocalDateTime.now());
            Query query = new Query(Criteria.where("id").is(subject.getId()));
            Update update = new Update();
            mongoTemplate.updateFirst(query, update, Subject.class);
            return true;
        }
        return false;
    }

    @Override
    public List<Subject> getSubjects(Subject subjectParam) {
        // 作为服务，要对入参进行判断，不能假设被调用时，入参一定正确
        if (subjectParam == null) {
            return null;
        }

        String type = subjectParam.getSubjectType();
        String subType = subjectParam.getSubjectSubType();
        String master = subjectParam.getMaster();

        // 作为服务，要对入参进行判断，不能假设被调用时，入参一定正确
        if (!StringUtils.hasText(type)) {
            return null;
        }

        // 总条件
        Criteria criteria = new Criteria();
        // 可能有多个子条件
        List<Criteria> subCris = new ArrayList();
        subCris.add(Criteria.where("subjectType").is(type));

        if (StringUtils.hasText(subType)) {
            subCris.add(Criteria.where("subjectSubType").is(subType));
        }

        if (StringUtils.hasText(master)) {
            subCris.add(Criteria.where("master").is(master));
        }

        // 三个子条件以 and 关键词连接成总条件对象，相当于 name='' and lyrics='' and subjectId=''
        criteria.andOperator(subCris.toArray(new Criteria[]{}));

        // 条件对象构建查询对象
        Query query = new Query(criteria);

        // 查询结果
        List<Subject> subjects = mongoTemplate.find(query, Subject.class);

        return subjects;
    }
}
